package com.laicunba.service.fuiou.impl;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.laicunba.constant.GloabConstant;
import com.laicunba.service.fuiou.FuiouStatusQueryService;
import com.laicunba.util.AssertUtil;
import com.laicunba.util.HttpUtil;
import com.laicunba.util.MD5Util;
import com.laicunba.util.SessionUtil;
import com.laicunba.util.StringUtil;

@SuppressWarnings({ "rawtypes", "unchecked" })
@Service
public class FuiouStatusQueryServiceImpl implements FuiouStatusQueryService {
	private static final Logger LOG = Logger.getLogger(FuiouStatusQueryServiceImpl.class);

	@Override
	public List<Result> query(String busicd, String startdt, String enddt) {
		return parseXMLResult(queryForXmlResult(busicd, startdt, enddt));
	}

	private String getValue(Document doc, String tagName) {
		NodeList nodeList = doc.getElementsByTagName(tagName);
		if (nodeList == null || nodeList.getLength() == 0) {
			return null;
		}
		Element e = (Element) nodeList.item(0);
		return e.getTextContent();
	}

	private String getValue(Element doc, String tagName) {
		NodeList nodeList = doc.getElementsByTagName(tagName);
		if (nodeList == null || nodeList.getLength() == 0) {
			return null;
		}
		Element e = (Element) nodeList.item(0);
		return e.getTextContent();
	}

	@Override
	public String queryForXmlResult(String busicd, String startdt, String enddt) {
		StringBuilder builder = new StringBuilder();
		builder.append("<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?> ");
		builder.append("<qrytransreq>").append("<ver>1.00</ver> ");
		builder.append("<busicd>").append(busicd).append("</busicd>");
		builder.append("<startdt>").append(startdt).append("</startdt>");
		builder.append("<enddt>").append(enddt).append("</enddt>");
		builder.append("</qrytransreq>");
		Map p = new HashMap();
		p.put("merid", GloabConstant.FUIOU_MCHNTCD);
		p.put("reqtype", "qrytransreq");
		p.put("xml", builder.toString());
		p.put("mac", MD5Util.md5Hex(GloabConstant.FUIOU_MCHNTCD + "|" + GloabConstant.FUIOU_MCHNT_KEY + "|qrytransreq|" + builder.toString()));
		LOG.info(String.format("[rid:%s,tag:FUIOU_PAY_FOR_REQ_POST]\t%s", SessionUtil.RID.get(), p.toString()));
		try {
			return HttpUtil.doPost(GloabConstant.FUIOU_PAYFORREQ_PREFIX, p);
		} catch (IOException e) {
			LOG.error(String.format("[rid:%s,tag:FUIOU_QRY_TRANS_REQ_POST_ERROR]", SessionUtil.RID.get()), e);
			AssertUtil.assertFail("FUIOU_PAY_FOR_REQ_POST_ERROR");
		} catch (Exception e) {
			AssertUtil.assertFail("FUIOU_PAY_FOR_REQ_POST_ERROR4");
		}
		return null;
	}

	@Override
	public List<Result> parseXMLResult(String xmlResult) {
		try {
			if (StringUtil.isEmpty(xmlResult)) {
				return null;
			}
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder docBuilder;

			docBuilder = factory.newDocumentBuilder();
			Document doc = docBuilder.parse(new ByteArrayInputStream(xmlResult.getBytes()));
			if (!"000000".equals(getValue(doc, "ret"))) {
				return null;
			}
			List list = new ArrayList();
			NodeList transNodeList = doc.getElementsByTagName("trans");
			if (transNodeList != null && transNodeList.getLength() > 0) {
				Element node = null;
				for (int i = 0; i < transNodeList.getLength(); i++) {
					node = (Element) transNodeList.item(i);
					FuiouStatusQueryService.Result result = new FuiouStatusQueryService.Result();
					result.setAccntnm(getValue(node, "accntnm"));
					result.setAccntno(getValue(node, "accntno"));
					result.setAmt(getValue(node, "amt"));
					result.setEntseq(getValue(node, "entseq"));
					result.setMemo(getValue(node, "memo"));
					result.setOrderno(getValue(node, "orderno"));
					result.setReason(getValue(node, "reason"));
					result.setResult(getValue(node, "result"));
					result.setState(getValue(node, "state"));
					list.add(result);
				}
			}
			return list;
		} catch (IOException e) {
			LOG.error(String.format("[rid:%s,tag:FUIOU_QRY_TRANS_REQ_POST_ERROR]", SessionUtil.RID.get()), e);
			AssertUtil.assertFail("FUIOU_PAY_FOR_REQ_POST_ERROR");
		} catch (ParserConfigurationException e) {
			LOG.error(String.format("[rid:%s,tag:FUIOU_RESULT_XML_ERROR1]", SessionUtil.RID.get()), e);
		} catch (SAXException e) {
			LOG.error(String.format("[rid:%s,tag:FUIOU_RESULT_XML_ERROR2]", SessionUtil.RID.get()), e);
		} catch (Exception e) {
			LOG.error(String.format("[rid:%s,tag:FUIOU_RESULT_XML_ERROR3]", SessionUtil.RID.get()), e);
		}
		return null;
	}

}
